--[[
    这份文件是官方的食谱相关的，经常写烹饪锅类的mod的小伙伴应该都见过不少次
    里面主要是官方提供的一系列方法，比如说计算食谱等等
]]
--[[小结
    1.根据这份文件，可以了解到官方的食谱系统是如何运作的
    2.添加食谱的流程
        1.定义食谱recipe
        2.如果recipe中有的材料没有没有营养属性（即无法入锅），需要通过AddIngredientValues设置营养属性
        3.通过AddCookerRecipe添加食谱到指定的烹饪器具的食谱表中
        4.如果想让自己的食谱出现在游戏内的食谱卡上，则还需要通过AddRecipeCard添加食谱卡片

]]

--[[精简解读，如果看不明白的就继续往下看详细标注
    文件提供的内容
        1.全局函数
            1.AddIngredientValues
            作用：添加食材的营养成分，也叫做让食材可以入锅
            --参数：
                --names：需要添加的可以入锅的食材表，注意一定要是表，即使只添加一个食材，也要用表包装一下，比如{"meat", "smallmeat"}
                --tags：营养成分表，该食材拥有的营养属性，用于后续判断能够通过配方的test，比如{meat = 1, smallmeat = 1}
                --cancook：是否有煮熟版本，如果是true，则会在食材营养表中添加一个names_cooked键，值为tags
                --candry：是否有晾干版本，如果是true，则会在食材营养表中添加一个names_dried键，值为tags
            --返回值：
                --无

            2.GetCandidateRecipes
            作用：获取可以制作的食谱
            --参数：
                --cooker：烹饪器具，比如"cookpot"
                --ingdata：通过GetIngredientValues函数整理后的食材列表，比如{tags = {fruit = 1, meat = 3}, names = {meat = 1, smallmeat = 3}}
            --返回值：
                --返回一张表，表中的内容要么是空，要么就是可以制作的recipe，注意如果传入的ingdata符合多个recipe的test，那么最终返回的表中会包含多个recipe，他们的优先级相同



            3.AddCookerRecipe
            作用：添加烹饪器具的食谱
            --参数：
                --cooker：烹饪器具，比如"cookpot"
                --recipe：食谱的定义表，比如火龙果派食谱定义表
                --is_mod_food：是否是模组食谱，如果是true，则会将食谱分类为mod，即设置recipe的cookbook_category属性为‘mod’
            --返回值：
                --无

            
            4.AddRecipeCard
            作用：添加食谱卡片
            --参数：
                --cooker：制作该食谱的烹饪器具，比如"cookpot"，这里主要是让卡片显示哪个烹饪器具可以制作该配方
                --recipe：食谱的定义表，比如火龙果派食谱定义表
            --返回值：
                --无

            
            5.IsModCookingProduct
            作用：检查是否是模组食谱产物
            --参数：
                --cooker：烹饪器具，比如"cookpot"
                --name：食谱的名称，比如火龙果派这种
            --返回值：
                --是否是模组食谱产物






        2.返回的本地函数和表
            1.CalculateRecipe
            作用：根据传入的厨具和食材，计算出本次烹饪的结果
            --参数：
                --cooker：烹饪器具，比如"cookpot"
                --names：食材表，比如{"meat", "smallmeat"}，即玩家放入锅里的四个食材
            --返回值：
                --食谱的名称和对应的烹饪时间


            2.IsCookingIngredient
            作用：检查是否是可烹饪食材，即食物能否入锅
            --参数：
                --prefabname：食材的prefab名，比如"meat"
            --返回值：
                --是否是烹饪食材


            3.GetRecipe
            作用：获取指定烹饪器具的指定食谱
            --参数：
                --cooker：烹饪器具，比如"cookpot"
                --product：食谱的名称，比如火龙果派这种
            --返回值：
                --火龙果派的食谱定义表



            4.HasModCookerFood
            作用：检查是否存在模组食谱，给烹饪指南用的
            --参数：
                    无
            --返回值：
                --是否存在模组食谱
            

            5.IsModCookerFood
            作用：检查是否是模组食谱产物
            --参数：
                --prefab：食材的prefab名，比如神话里蟠桃盛宴
            --返回值：
                --是否是模组食谱产物
            

                
            --以下是表
            6.recipes：即cookerrecipes表，存储了每个烹饪器具中的食谱，通过AddCookerRecipe添加，格式大概是这样:
                    cookerrecipes = 
                    {
                        cookpot = 
                        {
                            火龙果派prefab名 = 火龙果派recipe(就是在写食谱的时候定义的那个表，里面包含name、test、priority等等一系列食谱定义的那张表)
                            注意一下，如果通过AddCookerRecipe添加的时候，第三个参数传入了true，对应食物的recipe会额外添加一个cookbook_category字段，值为mod
                            如果传的是false，系统会自动设置cookbook_atlas字段为 "images/cookbook_"..recipe.name..".xml"
                        },
                        portablecookpot = {
                            土豆羹prefab名 = 土豆羹recipe
                        },
                    }

            7.ingredients：即ingredients表，存储了每个食材的营养成分，通过AddIngredientValues添加，格式大概是这样，其中cooked和dried可以通过AddIngredientValues的第三第四两个参数快捷添加，也可以自己写，不过快捷添加的话，营养成分默认和普通版本一样
                ingredients = 
                    {
                        xxx = 
                        {
                            tags = 
                            {
                                tagname = 1
                                tagname2 = 2
                            }
                        }
                        xxx_cooked = 
                        {
                            tags = 
                            {
                                precook = 1
                                tagname = 1
                                tagname2 = 2
                            }
                        }
                        xxx_dried = 
                        {
                            tags = 
                            {
                                dried = 1
                                tagname = 1
                                tagname2 = 2
                            }
                        }
                    }

            8.cookbook_recipes：烹饪指南类别表，键名是固定的五个，对应到游戏中的烹饪指南的三个类别，通过AddCookerRecipe添加食谱时，会自动根据食谱的cookbook_category字段添加到对应的类别中，格式大概是这样:
                cookbook_recipes = 
                {
                    mod = {
                        xxx = xxxrecipe
                    }
                    cookpot = {
                        xxx = xxxrecipe
                    }
                    portablecookpot = {
                        xxx = xxxrecipe
                    }
                    注意，cookbook_recipes的键名是固定的五个，对应到游戏中的食谱书
                    分别是mod（模组食物），cookpot（烹饪锅食谱），portablecookpot（大厨特色菜），spiced_cookpot(烹饪锅食谱调味版)，spiced_portablecookpot(大厨特色菜调味版)
                    不过虽然有五个，但是spiced_cookpot在烹饪指南中会被归类到cookpot中，spiced_portablecookpot会被归类到portablecookpot中
                }
                
            9.recipe_cards：食谱卡片表， 通过AddRecipeCard添加，格式大概如下
                recipe_cards = {
                    {recipe_name = "火龙果派", cooker_name = "cookpot"}
                }
]]

require "tuning"

--官方食谱
--格式为:{火龙果派 = true,土豆羹 = true}，键值就是食谱的prefab名，值是true
--通过AddCookerRecipe函数且第三个参数为false时添加到该表中
local official_foods = {}

--烹饪器具的食谱表
--[[
    格式大概是这样:
    cookerrecipes = 
    {
        cookpot = 
        {
            火龙果派prefab名 = 火龙果派recipe(就是在写食谱的时候定义的那个表，里面包含name、test、priority等等一系列食谱定义的那张表)
            注意一下，如果通过AddCookerRecipe添加的时候，第三个参数传入了true，对应食物的recipe会额外添加一个cookbook_category字段，值为mod
            如果传的是false，系统会自动设置cookbook_atlas字段为 "images/cookbook_"..recipe.name..".xml"
        },
        portablecookpot = {
            土豆羹prefab名 = 土豆羹recipe
        },
    }

]]
local cookerrecipes = {}


--需要添加到食谱书中的食谱表
--[[
    1.格式大概是
    cookbook_recipes = 
    {
        mod = {
            xxx = xxxrecipe
        }
        cookpot = {
            xxx = xxxrecipe
        }
        portablecookpot = {
            xxx = xxxrecipe
        }
        注意，cookbook_recipes的键名是固定的五个，对应到游戏中的食谱书
        分别是mod（模组食物），cookpot（烹饪锅食谱），portablecookpot（大厨特色菜），spiced_cookpot(烹饪锅食谱调味版)，spiced_portablecookpot(大厨特色菜调味版)
        不过虽然有五个，但是spiced_cookpot在烹饪指南中会被归类到cookpot中，spiced_portablecookpot会被归类到portablecookpot中
    }
]]
local cookbook_recipes = {}

local MOD_COOKBOOK_CATEGORY = "mod"
--以下是官方的注释，先版本的熟食都是批量制作的，命名格式为xx_cooked,但是早期的一些熟食，比如煮熟的大小肉这些，就不是这么命名的，所以官方写了这么一个表来作映射
--our naming conventions aren't completely consistent, sadly
local aliases =
{
	cookedsmallmeat = "smallmeat_cooked",
	cookedmonstermeat = "monstermeat_cooked",
	cookedmeat = "meat_cooked",
}

--食材营养表
--[[大概格式如下
    ingredients = 
    {
        xxx = 
        {
            tags = 
            {
                tagname = 1
                tagname2 = 2
            }
        }
        xxx_cooked = 
        {
            tags = 
            {
                precook = 1
                tagname = 1
                tagname2 = 2
            }
        }
        xxx_dried = 
        {
            tags = 
            {
                dried = 1
                tagname = 1
                tagname2 = 2
            }
        }
    }
]]
local ingredients = {}

--食谱卡片表
--[[
    格式大概如下
    recipe_cards = {
        {recipe_name = "火龙果派", cooker_name = "cookpot"}
    }
]]
local recipe_cards = {}





-------------------------------------------------------------------------------------------------------------------------------------------------文件提供的全局函数和变量-------------------------------------------------------------------------------------------------------------------------------------------------


--获取配方的营养成分和食材
--最后返回的一个包含营养成分和食材数量的表
--比如：tags = {fruit = 1, meat = 3}, names = {meat = 1, smallmeat = 3}，表示本次烹饪,玩家放入了1大肉，3小肉，这些食材蕴含了1水果营养和3肉类营养
--后续系统就可以根据包含的营养以及检查是否含有指定的原料来匹配食谱
local function GetIngredientValues(prefablist)
    local prefabs = {}
    local tags = {}
    --遍历食材列表，也就是玩家放在锅里面的食材
    for k,v in pairs(prefablist) do
        --如果在映射表中，就将映射后的名字赋值给name
        local name = aliases[v] or v
        --检查 prefabs 表中是否存在键为 name 的条目，不存在则初始化为0，存在则加1，用来记录食材的数量，最后prefabs表内容是{xxx = 1, xxx = 2}
        prefabs[name] = (prefabs[name] or 0) + 1
        local data = ingredients[name]
        if data ~= nil then
            for kk, vv in pairs(data.tags) do
                tags[kk] = (tags[kk] or 0) + vv
            end
        end
    end
    return { tags = tags, names = prefabs }
end

--给食材添加营养成分
--比如我要让一个金块可以作为原料放入锅内，那么就需要给金块添加营养成分
--names：食材列表，比如{"gold"}
--tags：营养成分，比如{fruit = 1, meat = 3}
--cancook：是否可以烹饪，比如true
--candry：是否可以干燥，比如true
--当cancook和candry被赋值为true时，会自动将食物（这里是金块）的cooked版本和dried版本也添加营养成分
--如果希望三个版本营养成分不同，则不应该传入这两个参数，重新将另外两个版本作为names重新传入函数
--通过cancook和candry生成的两个版本的营养表会有一个额外的标记字段，precook和dried，方便后续判断，所以自己单独写特殊版本的时候也建议传进去
function AddIngredientValues(names, tags, cancook, candry)
	for _,name in pairs(names) do
		ingredients[name] = { tags= {}}



		if cancook then
			ingredients[name.."_cooked"] = {tags={}}
		end

		if candry then
			ingredients[name.."_dried"] = {tags={}}
		end

        --[[
            ingredients = 
            {
                xxx = 
                {
                    tags = {}
                }
                xxx_cooked = 
                {
                    tags = {}
                }
                xxx_dried = 
                {
                    tags = {}
                }
            }
        ]]

		for tagname,tagval in pairs(tags) do
			ingredients[name].tags[tagname] = tagval


			if cancook then
				ingredients[name.."_cooked"].tags.precook = 1
				ingredients[name.."_cooked"].tags[tagname] = tagval
			end
			if candry then
				ingredients[name.."_dried"].tags.dried = 1
				ingredients[name.."_dried"].tags[tagname] = tagval
			end
		end
	end
end

--根据传入的食物，找到所有可以制作的食谱，然后按优先级顺序返回最高优先级的食谱
--这个函数是决定烹饪锅烹饪结果的关键函数
--cooker：烹饪锅的类型，比如"cookpot"
--ingdata：整理后的食材列表，比如{tags = {fruit = 1, meat = 3}, names = {meat = 1, smallmeat = 3}}
--返回一个空表（如果ingdata不能制作任何食谱）
--或一个包含可制作食谱的表（如果ingdata可制作的食谱中只存在单一最高优先级的食谱，则返回的表中只有该元素，否则返回的表中是多个食谱，他们的优先级相同）
function GetCandidateRecipes(cooker, ingdata)
    -- 获取对应容器的所有食谱
	local recipes = cookerrecipes[cooker] or {}
	local candidates = {}

	--find all potentially valid recipes
    --遍历对应厨具的食谱，查找本次传入的食材（也就是ingdata）能够制作的哪些食物
	for k,v in pairs(recipes) do
		if v.test(cooker, ingdata.names, ingdata.tags) then
            --如果通过食谱的test测试，直接将该食谱添加到candidates表中
            --从这也可以看出，食谱test测试的函数参数分别是厨具、食材表{xxx = 1, xxx = 2}、营养表{fruit = 1, meat = 3}
            --到这一步，candidates的表示为{ xxxrecipe, xxx2recipe}，其中内容是通过食谱recipe的test测试函数的recipe本身
			table.insert(candidates, v)
		end
	end

    --按照配方的priority对candidates进行排序，priority越大，优先级越高
    --table.sort是内置的排序方法，后面的比较函数的参数ab是自动从candidates中取出来的两个元素
	table.sort( candidates, function(a,b) return (a.priority or 0) > (b.priority or 0) end )

    --如果candidates表不为空，即找到了可以制作的食谱，继续执行
	if #candidates > 0 then
		--find the set of highest priority recipes
		local top_candidates = {}
		local idx = 1
		local val = candidates[1].priority or 0

        --遍历candidates表，将priority最大的食谱添加到top_candidates表中
        --这一步是为了兼容多个recipe的priority相同
        --如果存在这种情况，则将所有priority相同的食谱添加到top_candidates表中返回
        --如果没有，则返回的top_candidates表中就只有一个元素，即priority最大的食谱
		for k,v in ipairs(candidates) do
			if k > 1 and (v.priority or 0) < val then
				break
			end
			table.insert(top_candidates, v)
		end
		return top_candidates
	end

    --如果没找到可以制作的食谱，默认返回candidates表，注意此时candidates是空表
	return candidates
end

--[[
向指定的烹饪器具注册一个食谱，并将其添加到游戏的烹饪系统和食谱书中。
官方目前有的厨具包括：
    cookpot：普通烹饪锅
    portablecookpot：厨子的便携烹饪锅
    archive_cookpot：远古烹饪锅
    portablespicer：厨子的香料研磨器
recipe是定义的配方表
is_mod_food：是否是模组食谱，如果是，则将其分类为mod
]]
function AddCookerRecipe(cooker, recipe, is_mod_food)
    --如果食谱是模组食谱，则将其分类为mod
	if is_mod_food then
		recipe.cookbook_category = MOD_COOKBOOK_CATEGORY
	else
		--如果食谱是官方食谱，则将其分类为official
		official_foods[recipe.name] = true
         -- 设置高清图集路径
		recipe.cookbook_atlas = "images/cookbook_"..recipe.name..".xml" -- use the high res images
	end

    --初始化烹饪器具的食谱表
    --到这一步初始化完毕后，cookerrecipes的格式差不多是{cookpot = {}，portablecookpot = {}，archive_cookpot = {}，portablespicer = {}}
	if not cookerrecipes[cooker] then
		cookerrecipes[cooker] = {}
	end
    
    --将食谱添加到对应烹饪器具的食谱表中
	cookerrecipes[cooker][recipe.name] = recipe

    --对香料研磨器的特殊处理
    --非香料研磨器和没有设置no_cookbook的食谱会被添加到食谱书中
	if cooker ~= "portablespicer" and not recipe.no_cookbook then
		if not cookbook_recipes[recipe.cookbook_category] then
			cookbook_recipes[recipe.cookbook_category] = {}
		end
		if not cookbook_recipes[recipe.cookbook_category][recipe.name] then
			cookbook_recipes[recipe.cookbook_category][recipe.name] = recipe
		end
	end
end

--将指定配方添加到食物卡片中
--参数：
    --cooker：制作该食谱的烹饪器具，比如"cookpot"，这里主要是让卡片显示哪个烹饪器具可以制作该配方
    --recipe：食谱的定义表，比如火龙果派的食谱定义表
function AddRecipeCard(cooker, recipe)
	table.insert(recipe_cards, {recipe_name = recipe.name, cooker_name = cooker})
end

--[[检查是否是模组产物
--参数：
    --cooker：烹饪器具，比如"cookpot"
    --name：食谱的名称，比如火龙果派这种
--返回值：
    --是否是模组产物
--关于cookerrecipes属性，在modutil.lua中明确有写，mod初始化时通过env.cookerrecipes = {}在mod环境中创建该表
--后续mod通过AddCookerRecipe，会通过以下代码将食谱名称添加到记录中
    --如果该烹饪器还没有记录，创建空数组
    -- if env.cookerrecipes[cooker] == nil then
    --     env.cookerrecipes[cooker] = {}
    -- end
    
    -- -- 将新食谱名称添加到记录中
    -- if recipe.name then
    --     table.insert(env.cookerrecipes[cooker], recipe.name)
    -- end
]]
function IsModCookingProduct(cooker, name)
	local enabledmods = ModManager:GetEnabledModNames()
    for i,v in ipairs(enabledmods) do
        local mod = ModManager:GetMod(v)
        if mod.cookerrecipes and mod.cookerrecipes[cooker] and table.contains(mod.cookerrecipes[cooker], name) then
            return true
        end
    end
    return false
end


--是否是模组食物
--判断依据就是官方食谱表中是否存在该键
local function IsModCookerFood(prefab)
	return not official_foods[prefab] -- note: we cannot test against cookbook_recipes[MOD_COOKBOOK_CATEGORY] because if the mod is unloaded, it would return true
end



--是否存在模组食谱，盲猜是给烹饪指南提供显示模组食物标签的依据
--判断依据就是cookbook_recipes表中是否存在MOD_COOKBOOK_CATEGORY键
local function HasModCookerFood()
	return cookbook_recipes[MOD_COOKBOOK_CATEGORY] ~= nil
end

--获取对应烹饪器具的的指定食谱
--参数：
    --cooker：烹饪器具，比如"cookpot"
    --product：食谱的名称，比如火龙果派这种
--返回值：
    --火龙果派的食谱定义表
local function GetRecipe(cooker, product)
	local recipes = cookerrecipes[cooker] or {}
	return recipes[product]
end

--是否在食材营养表中
--判断依据就是食材营养表中是否存在该键，或者aliases映射表中是否有该键的映射键
local function IsCookingIngredient(prefabname)
    return ingredients[aliases[prefabname] or prefabname] ~= nil
end

--计算食谱
--参数：
    --cooker：烹饪器具，比如"cookpot"
    --names：食材表，比如{"meat", "smallmeat"}，即玩家放入锅里的四个食材
--返回值：
    --食谱的名称和对应的烹饪时间
local function CalculateRecipe(cooker, names)
    --这一步首先将传入的食材统计整理成两个表
    --ingdata = {tags = {fruit = 1, meat = 3}, names = {meat = 1, smallmeat = 3}}
	local ingdata = GetIngredientValues(names) 

    --获取可以制作的食谱表
	local candidates = GetCandidateRecipes(cooker, ingdata)

    --按照配方的weight对candidates进行排序，weight越大，优先级越高
    --weight就是专门处理配方的priority相同时，随机到的概率
	table.sort( candidates, function(a,b) return (a.weight or 1) > (b.weight or 1) end )

    --计算总权重
	local total = 0
	for k,v in pairs(candidates) do
		total = total + (v.weight or 1)
	end

    --轮盘赌算法，从多个候选食谱中，根据各自的权重（weight）随机选择一个食谱
    --首先确定一个随机数，范围是0到总权重
	local val = math.random()*total
	local idx = 1

    --开始循环，最大循环次数为candidates中的元素数量
	while idx <= #candidates do

        --想象一个数轴，数轴的起点是0，终点是总权重，每个食谱的权重是数轴上的一个点
        --val是随机数，每次循环减去一个食谱的权重，如果减去后小于等于0，则说明随机数落在了该食谱的权重范围内，返回该食谱，否则进行下一次循环
        --这样就保证了每个食谱被选中的概率与其权重成正比
		val = val - candidates[idx].weight  
		if val <= 0 then
			return candidates[idx].name, candidates[idx].cooktime or 1
		end

		idx = idx+1
	end
end




-------------------------------------------------------------------------------------------------------------------------------------------------官方批处理原版游戏中的相关内容------------------------------------------------------------------------------------------------------------------------------------------------




-- All Tags: fruit, monster, sweetener, veggie, meat, fish, egg, decoration, fat, dairy, inedible, seed, magic
local fruits = {"pomegranate", "dragonfruit", "cave_banana"}
AddIngredientValues(fruits, {fruit=1}, true)

AddIngredientValues({"wormlight"}, {fruit=1})
AddIngredientValues({"wormlight_lesser"}, {fruit=.5})

AddIngredientValues({"berries"}, {fruit=.5}, true)
AddIngredientValues({"berries_juicy"}, {fruit=.5}, true)
AddIngredientValues({"fig"}, {fruit=.5}, true)
AddIngredientValues({"durian"}, {fruit=1, monster=1}, true)

AddIngredientValues({"honey", "honeycomb"}, {sweetener=1}, true)
AddIngredientValues({"royal_jelly"}, {sweetener=3}, true)

local veggies = {"carrot", "corn", "pumpkin", "eggplant", "cutlichen", "asparagus", "onion", "garlic", "tomato", "potato", "pepper"}
AddIngredientValues(veggies, {veggie=1}, true)

local mushrooms = {"red_cap", "green_cap", "blue_cap", "moon_cap"}
AddIngredientValues(mushrooms, {veggie=.5}, true)

AddIngredientValues({"meat"}, {meat=1}, true, true)
AddIngredientValues({"monstermeat"}, {meat=1, monster=1}, true, true)
AddIngredientValues({"froglegs", "drumstick", "batwing"}, {meat=.5}, true)
AddIngredientValues({"smallmeat", "batnose"}, {meat=.5}, true, true)

AddIngredientValues({"eel"}, {meat=.5,fish=1}, true)
AddIngredientValues({"fish"}, {meat=1,fish=1}, true)

AddIngredientValues({"pondeel"}, {meat=.5,fish=1}, true)
AddIngredientValues({"pondfish"}, {meat=.5,fish=.5}, false)
AddIngredientValues({"fishmeat_small"}, {meat=.5,fish=.5}, true)
AddIngredientValues({"fishmeat"}, {meat=1,fish=1}, true)
local oceanfishdefs = require("prefabs/oceanfishdef")
for _, fish_def in pairs(oceanfishdefs.fish) do
	if fish_def.cooker_ingredient_value ~= nil then
		AddIngredientValues({fish_def.prefab.."_inv"}, fish_def.cooker_ingredient_value, false)
	end
end

AddIngredientValues({"kelp"}, {veggie=.5}, true, true)

AddIngredientValues({"mandrake"}, {veggie=1, magic=1}, true)
AddIngredientValues({"egg"}, {egg=1}, true)
AddIngredientValues({"tallbirdegg"}, {egg=4}, true)
AddIngredientValues({"bird_egg"}, {egg=1}, true)
AddIngredientValues({"butterflywings"}, {decoration=2})
AddIngredientValues({"moonbutterflywings"}, {decoration=2})
AddIngredientValues({"butter"}, {fat=1, dairy=1})
AddIngredientValues({"twigs"}, {inedible=1})
AddIngredientValues({"lightninggoathorn"}, {inedible=1})

AddIngredientValues({"ice"}, {frozen=1})
AddIngredientValues({"mole"}, {meat=.5})
AddIngredientValues({"cactus_meat"}, {veggie=1}, true)
AddIngredientValues({"rock_avocado_fruit_ripe"}, {veggie=1}, true)
AddIngredientValues({"watermelon"}, {fruit=1}, true)
AddIngredientValues({"cactus_flower"}, {veggie=.5})
AddIngredientValues({"acorn"}, {seed=1})
AddIngredientValues({"acorn_cooked"}, {seed=1})
AddIngredientValues({"goatmilk"}, {dairy=1})
-- AddIngredientValues({"seeds"}, {seed=1}, true)

AddIngredientValues({"milkywhites"}, {dairy=1})

AddIngredientValues({"nightmarefuel"}, {inedible=1, magic=1})
AddIngredientValues({"boneshard"}, {inedible=1})

AddIngredientValues({"wobster_sheller_land"}, {meat=1.0, fish=1.0})

AddIngredientValues({"barnacle","barnacle_cooked"}, {meat=0.25, fish=0.25})

AddIngredientValues({"plantmeat","plantmeat_cooked"}, {meat=1})

AddIngredientValues({"refined_dust"}, {decoration=2})

AddIngredientValues({"forgetmelots"}, {decoration=1})

AddIngredientValues({"trunk_summer","trunk_winter","trunk_cooked"}, {meat=1})

AddIngredientValues({"ancientfruit_nightvision"}, {fruit=1}, true)





local foods = require("preparedfoods")
for k,recipe in pairs (foods) do
	AddCookerRecipe("cookpot", recipe)
	AddCookerRecipe("portablecookpot", recipe)
	AddCookerRecipe("archive_cookpot", recipe)

	if recipe.card_def then
		AddRecipeCard("cookpot", recipe)
	end
end

local portable_foods = require("preparedfoods_warly")
for k,recipe in pairs (portable_foods) do
	AddCookerRecipe("portablecookpot", recipe)
end

local spicedfoods = require("spicedfoods")
for k, recipe in pairs(spicedfoods) do
    AddCookerRecipe("portablespicer", recipe)
end

local nonfoods = require("preparednonfoods")
for k, recipe in pairs(nonfoods) do
    AddCookerRecipe("cookpot", recipe)
    AddCookerRecipe("portablecookpot", recipe)
    AddCookerRecipe("archive_cookpot", recipe)
end



















return 
{ 
	CalculateRecipe = CalculateRecipe, 
	IsCookingIngredient = IsCookingIngredient,
	recipes = cookerrecipes, 
	ingredients = ingredients,
	GetRecipe = GetRecipe, 
	cookbook_recipes = cookbook_recipes,
	recipe_cards = recipe_cards, 
	HasModCookerFood = HasModCookerFood, 
	IsModCookerFood = IsModCookerFood
}
